#region Copyright and Licensing Notice
// Copyright (C) 2011 Steven Bosnick
// 
// This program is open source software; you can redistribute it 
// and/or modifiy it under the terms of the Eclipse Public License,
// version 1.0.
// 
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A 
// PARTICULAR PURPOSE. See the Eclipse Public License for more
// details.
// 
// You should have received a copy of the Eclipse Public License 
// along with this program; if not, you can find a copy at
// "http://www.opensource.org/licenses/eclipse-1.0.php".
#endregion
using System;
using BitwiseOre.SharedMemory.Core.Threading;
using NUnit.Framework;
using Moq;

namespace BitwiseOre.Tests.SharedMemory.Threading
{
    [TestFixture]
    public sealed class TimeoutHelperFixture : AssertionHelper
    {
        [Test(Description = "Ensures that construcitng a helper with a negative timeout throws an exception")]
        public void Construct_WithNegativeTimeout()
        {
            Expect(() => new TimeoutHelper(TimeSpan.FromSeconds(-1), null),
                   Throws.InstanceOf<ArgumentOutOfRangeException>());
        }

        [Test(Description = "Checks that the remaining time is calculated with reference to the elapsed clock time")]
        public void RemainingTime_WithAdvancingClock()
        {
            var clock = new Mock<IClock>();
            var times = new[]
                            {
                                new DateTime(2010, 12, 15, 12, 0, 0),
                                new DateTime(2010, 12, 15, 12, 1, 0)
                            };
            var count = 0;
            clock.SetupGet(c => c.Now).Returns(() => times[count++]);
            var helper = new TimeoutHelper(TimeSpan.FromMinutes(2), clock.Object);

            Expect(helper.RemainingTime, EqualTo(TimeSpan.FromMinutes(1)),
                "Remaining time not calculated in reference to the advancing clock time.");
        }

        [Test(Description = "Checks that the remaining time is returned as zero after the deadline has passed")]
        public void RemainingTime_AfterDealinePassed()
        {
            var clock = new Mock<IClock>();
            var times = new[]
                            {
                                new DateTime(2010, 12, 15, 12, 0, 0),
                                new DateTime(2010, 12, 15, 12, 2, 0)
                            };
            var count = 0;
            clock.SetupGet(c => c.Now).Returns(() => times[count++]);
            var helper = new TimeoutHelper(TimeSpan.FromMinutes(1), clock.Object);

            Expect(helper.RemainingTime, EqualTo(TimeSpan.Zero),
                "Remaining time not equeal to zero after the initial timeout has passed.");
        }

    }
}